package cn.shop.front.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.session.SaSessionCustomUtil;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.DesensitizedUtil;
import cn.hutool.core.util.StrUtil;
import cn.shop.front.entity.gamebind.GameBind;
import cn.shop.front.entity.req.*;
import cn.shop.front.service.FrontUserService;
import cn.shop.front.service.GameBindService;
import cn.shop.front.service.InboxService;
import cn.shop.front.util.CurrentUserUtil;
import cn.shop.transcation.frontUserModule.FrontUser;
import cn.shop.utils.ApiResult;
import cn.shop.utils.constant.Constant;
import cn.shop.validation.Update;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;

import static cn.shop.utils.ApiResult.fail;
import static cn.shop.utils.ApiResult.result;


/**
 * 用户信息相关接口
 *
 * @author jzw
 * @since 2022-01-07 15:45:19
 */
@Slf4j
@Validated
@SaCheckLogin
@RestController
@RequestMapping("/api/v1/frontUser")
public class FrontUserController {

	/**
	 * 服务对象
	 */
	@Resource
	private FrontUserService frontUserService;

	@Resource
	private InboxService inboxService;
	@Resource
	private GameBindService gameBindService;

	/**
	 * 获取登录人信息
	 *
	 * @author jzw
	 * @since 2022/1/7 17:33
	 */
	@GetMapping("userInfo")
	public ApiResult<FrontUser> userInfo() {
		FrontUser user = frontUserService.getById(CurrentUserUtil.getUserId());
		user.setWxBind(StrUtil.isNotBlank(user.getOpenId()));
		user.setName(DesensitizedUtil.chineseName(user.getName()));
		user.setIdentityCard(DesensitizedUtil.idCardNum(user.getIdentityCard(),2, 2));
		return ApiResult.success(user);
	}

	@GetMapping("/wxunbind")
	public ApiResult<Map<String, Object>> wxUnbind() {
		long userId = CurrentUserUtil.getUserId();
		return ApiResult.result(frontUserService.lambdaUpdate()
				.set(FrontUser::getOpenId, null)
				.eq(FrontUser::getId, userId)
				.update());
	}

	@GetMapping("/unregist")
	public ApiResult<Map<String, Object>> unregist(String code) {
		long userId = CurrentUserUtil.getUserId();
		FrontUser frontUser = frontUserService.getById(userId);
		if (frontUser.getBalance().doubleValue() > 0d) {
			return ApiResult.fail("请将余额全部提现后再注销账户！", null);
		}
		String key = Constant.SMS_CODE + userId;
		SaSession session = SaSessionCustomUtil.getSessionById(key);
		Assert.notNull(session, "验证码已失效");
		String c = session.getString("code");
		if (StrUtil.isBlank(c) || !c.equals(code)) {
			return fail("验证码不正确");
		}
		StpUtil.logout(userId);
		GameBind unbind = new GameBind();
		unbind.setUserId(userId);
		gameBindService.removeById(unbind);
		FrontUser remove = new FrontUser();
		remove.setId(userId);
		return ApiResult.result(frontUserService.removeById(remove));
	}

	/**
	 * 修改数据
	 *
	 * @param frontUser 实体对象
	 * @return 修改结果
	 * @author jzw
	 * @since 2022-01-07 15:45:19
	 */
	@PutMapping("update")
	public ApiResult<Map<String, Object>> update(@Validated(Update.class) @RequestBody FrontUser frontUser) {
		//只允许修改自己的信息
		long userId = CurrentUserUtil.getUserId();
		String key = Constant.SMS_CODE + userId;
		SaSession session = SaSessionCustomUtil.getSessionById(key);
		Assert.notNull(session, "验证码已失效");
		String c = session.getString("code");
		log.info("获取缓存验证码：key={}，code={}，session={}, 前端code={}", key, c, session, frontUser.getCode());
		if (StrUtil.isBlank(c) || !c.equals(frontUser.getCode())) {
			return fail("验证码不正确");
		}
		session.clear();
		frontUser.setId(userId);
		return result(frontUserService.updateById(frontUser));
	}

	/**
	 * 修改数据
	 *
	 * @param frontUser 实体对象
	 * @return 修改结果
	 * @author jzw
	 * @since 2022-01-07 15:45:19
	 */
	@PutMapping("updatephone")
	public ApiResult<Map<String, Object>> updatePhone(@Validated @RequestBody UpdatePhoneReq frontUser) {
		//只允许修改自己的信息
		long userId = CurrentUserUtil.getUserId();
		String key = Constant.SMS_CODE + userId;
		SaSession session = SaSessionCustomUtil.getSessionById(key);
		Assert.notNull(session, "验证码已失效");
		String c = session.getString("code");
		log.info("获取缓存验证码：key={}，code={}，session={}, 前端code={}", key, c, session, frontUser.getCode());
		if (StrUtil.isBlank(c) || !c.equals(frontUser.getCode())) {
			return fail("验证码不正确");
		}
		session.clear();
		return result(frontUserService.lambdaUpdate()
				.set(FrontUser::getPhone, frontUser.getPhone())
				.eq(FrontUser::getId, userId).update());
	}

	/**
	 * 实名认证接口
	 *
	 * @param user 认证信息
	 * @return 返回结果
	 */

	@PutMapping("/verification")
	public ApiResult<Map<String, Object>> verification(@Validated @RequestBody VerificationReq user) {
		long userId = CurrentUserUtil.getUserId();
		if (StrUtil.isNotBlank(user.getCode())) {
			String key = Constant.SMS_CODE + userId;
			SaSession session = SaSessionCustomUtil.getSessionById(key);
			Assert.notNull(session, "验证码已失效");
			String c = session.getString("code");
			if (StrUtil.isBlank(c) || !c.equals(user.getCode())) {
				return fail("验证码不正确");
			}
			session.clear();
		}
		return frontUserService.realNameAuthentication(userId, user.getName(), user.getIdentityCard());
	}

	/**
	 * 设置交易密码接口
	 *
	 * @param user 交易密码
	 * @return 返回结果
	 */
	@PutMapping("/setTransactionPassword")
	public ApiResult<Map<String, Object>> setTransactionPassword(@Validated @RequestBody TransactionPasswordReq user) {
		long userId = CurrentUserUtil.getUserId();
		if (StrUtil.isNotBlank(user.getCode())) {
			String key = Constant.SMS_CODE + userId;
			SaSession session = SaSessionCustomUtil.getSessionById(key);
			Assert.notNull(session, "验证码已失效");
			String c = session.getString("code");
			if (StrUtil.isBlank(c) || !c.equals(user.getCode())) {
				return fail("验证码不正确");
			}
			session.clear();
		}
		return result(frontUserService.setTransactionPassword(userId, user.getTransactionPassword()));
	}

	/**
	 * 修改登录密码
	 *
	 * @param user 登录密码
	 * @return 返回结果
	 */
	@PutMapping("/updatePassword")
	public ApiResult<Map<String, Object>> updateLoginPassword(@Validated @RequestBody PasswordReq user) {
		long userId = CurrentUserUtil.getUserId();
		String key = Constant.SMS_CODE + userId;
		SaSession session = SaSessionCustomUtil.getSessionById(key);
		Assert.notNull(session, "验证码已失效");
		String c = session.getString("code");
		log.info("获取缓存验证码：key={}，code={}，session={}, 前端code={}", key, c, session, user.getCode());
		if (StrUtil.isBlank(c) || !c.equals(user.getCode())) {
			return fail("验证码不正确");
		}
		session.clear();
		StpUtil.logout(userId);
		return result(frontUserService.updateLoginPassword(userId, user.getPassword()));
	}

	/**
	 * 设置是否自动提现
	 *
	 * @param user 是否自动提现
	 * @return 返回结果
	 */
	@PutMapping("/setAutoWithdraw")
	public ApiResult<Map<String, Object>> updateAutoWithdraw(@Validated @RequestBody AutWithdrawReq user) {
		long userId = CurrentUserUtil.getUserId();
		return result(frontUserService.setAutoWithdraw(userId, user.getAutoWithdraw()));
	}

	/**
	 * 修改用户名
	 *
	 * @param user 用户名
	 * @return 返回结果
	 */
	@PutMapping("/rename")
	public ApiResult<Map<String, Object>> rename(@Validated @RequestBody RenameReq user) {
		long userId = CurrentUserUtil.getUserId();
		FrontUser u = frontUserService.lambdaQuery()
				.eq(FrontUser::getAccount, user.getAccount())
				.oneOpt().orElse(null);
		if (u != null && user.getAccount().equals(u.getAccount())) {
			return ApiResult.fail("该用户名已被人使用");
		}
		String key = Constant.SMS_CODE + userId;
		SaSession session = SaSessionCustomUtil.getSessionById(key);
		Assert.notNull(session, "验证码已失效");
		String c = session.getString("code");
		log.info("获取缓存验证码：key={}，code={}，session={}, 前端code={}", key, c, session, user.getCode());
		if (StrUtil.isBlank(c) || !c.equals(user.getCode())) {
			return fail("验证码不正确");
		}
		session.clear();
		StpUtil.logout(userId);

		return result(frontUserService.updateAccount(userId, user.getAccount()));
	}

	/**
	 * 获取当前登录人未读站内信数量
	 *
	 * @return 返回结果
	 */
	@GetMapping("/unreads")
	public ApiResult<Long> unreads() {
		return ApiResult.success(inboxService.getUnreadCount(CurrentUserUtil.getUserId()));
	}

	/**
	 * 获取站内信列表
	 *
	 * @return 返回结果
	 */
	@GetMapping("/inboxes")
	public ApiResult<List<Map<String, Object>>> inboxes() {
		return ApiResult.success(inboxService.inboxList(CurrentUserUtil.getUserId()));
	}

	/**
	 * 设置已读
	 *
	 * @param ids 编号
	 * @return 返回结果
	 */
	@PutMapping("/read")
	public ApiResult<Map<String, Object>> read(@RequestBody List<Long> ids) {
		return ApiResult.result(inboxService.read(ids));
	}
}
